package com.example.servlet.manager;

import com.example.entity.CityCount;
import com.example.entity.Manager;
import com.example.service.ManagerService;
import com.example.service.impl.ManagerServiceImpl;
import com.example.utils.MybatisUtil;
import com.example.utils.ThymeleafUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.ibatis.session.SqlSession;
import org.thymeleaf.context.Context;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@WebServlet("/manager_report")
public class mReportServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try (SqlSession session = MybatisUtil.getSession()){
            ManagerService service = new ManagerServiceImpl(session);
            Manager manager = (Manager) req.getSession().getAttribute("manager");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate now = LocalDate.now();  // 当前日期
            LocalDate firstDayOfThisMonth = now.withDayOfMonth(1);  // 本月第一天
            String firstDayStr = firstDayOfThisMonth.format(formatter);
            LocalDate lastDayOfThisMonth = now.withDayOfMonth(now.lengthOfMonth());  // 本月最后一天
            String lastDayStr = lastDayOfThisMonth.format(formatter);
            LocalDate previousMonth = now.minusMonths(1);  // 上个月
            LocalDate firstDayOfLastMonth = previousMonth.withDayOfMonth(1);  // 上个月第一天
            String firstDayOfLastMonthStr = firstDayOfLastMonth.format(formatter);
            LocalDate lastDayOfLastMonth = previousMonth.withDayOfMonth(previousMonth.lengthOfMonth());  // 上个月最后一天
            String lastDayOfLastMonthStr = lastDayOfLastMonth.format(formatter);

            Context context = new Context();
            if(service.getTotalMoney()!=null){
                context.setVariable("totalRevenue",service.getTotalMoney());
            }else{
                context.setVariable("totalRevenue",0);
            }
            BigDecimal totalRevenue1 = service.getTotalMoneyByDate(firstDayStr,lastDayStr);
            BigDecimal totalRevenue2 = service.getTotalMoneyByDate(firstDayOfLastMonthStr,lastDayOfLastMonthStr);
            BigDecimal difference = totalRevenue1.subtract(totalRevenue2);
            if (totalRevenue2.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal growthRate = difference
                        .divide(totalRevenue2, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
                context.setVariable("revenueChange", growthRate.doubleValue());
            } else {
                context.setVariable("revenueChange", 100.0);
            }
            context.setVariable("totalOrders",service.getOrderNum());
            int totalOrders1 = service.getOrderCountByLongDate(firstDayStr,lastDayStr);
            int totalOrders2 = service.getOrderCountByLongDate(firstDayOfLastMonthStr,lastDayOfLastMonthStr);
            if (totalOrders2 != 0) {
                double growthRate = (totalOrders1 - totalOrders2) / (double) totalOrders2 * 100;
                context.setVariable("orderChange", growthRate);
            }else{
                context.setVariable("orderChange", 100.0);
            }
            context.setVariable("totalFlights",service.getTotalFlightNum());
            int totalFlights1 = service.getTotalFlightNumByDate(firstDayStr,lastDayStr);
            int totalFlights2 = service.getTotalFlightNumByDate(firstDayOfLastMonthStr,lastDayOfLastMonthStr);
            if (totalFlights2 != 0) {
                double growthRate = (totalFlights1 - totalFlights2) / (double) totalFlights2 * 100;
                context.setVariable("flightChange", growthRate);
            }else{
                context.setVariable("flightChange", 100.0);
            }
            context.setVariable("totalUsers",service.getTotalUserNum());
            int totalUsers1 = service.getTotalUserNumByDate(firstDayStr,lastDayStr);
            int totalUsers2 = service.getTotalUserNumByDate(firstDayOfLastMonthStr,lastDayOfLastMonthStr);
            if (totalUsers2 != 0) {
                double growthRate = (totalUsers1 - totalUsers2) / (double) totalUsers2 * 100;
                context.setVariable("userChange", growthRate);
            }else{
                context.setVariable("userChange", 100.0);
            }

            int currentMonthValue = LocalDate.now().getMonth().getValue();  // 获取当前月份（1~12）
            List<String> revenueMonthLabels = new ArrayList<>();
            List<String> ordersMonthLabels = new ArrayList<>();
            List<String> userGrowthLabels = new ArrayList<>();
            for (int i = 1; i <= currentMonthValue; i++) {
                revenueMonthLabels.add(i + "月");
                ordersMonthLabels.add(i + "月");
                userGrowthLabels.add(i + "月");
            }
            context.setVariable("revenueMonthLabels", revenueMonthLabels);
            context.setVariable("ordersMonthLabels", ordersMonthLabels);
            context.setVariable("userGrowthLabels", userGrowthLabels);
            List<Double> revenueMonthData = new ArrayList<>();  // 获取每个月的收入数据
            List<Integer> ordersMonthData = new ArrayList<>();
            List<Integer> userGrowthData = new ArrayList<>();
            int year = LocalDate.now().getYear(); // 使用当前年份
            for (int month = 1; month <= currentMonthValue; month++) {
                // 获取这个月的第一天
                LocalDate fd = LocalDate.of(year, month, 1);
                String fds = fd.format(formatter);
                LocalDate ld = fd.withDayOfMonth(fd.lengthOfMonth()); // 获取这个月的最后一天
                String lds = ld.format(formatter);
                BigDecimal money = service.getTotalMoneyByDate(fds, lds);
                revenueMonthData.add(money.doubleValue());
                int orderNum = service.getOrderCountByLongDate(fds, lds);
                ordersMonthData.add(orderNum);
                int userNum = service.getTotalUserNumByDate(fds, lds);
                userGrowthData.add(userNum);
            }
            context.setVariable("revenueMonthData", revenueMonthData);
            context.setVariable("ordersMonthData", ordersMonthData);
            context.setVariable("userGrowthData", userGrowthData);
            int currentQuarterValue = (currentMonthValue - 1) / 3 + 1;
            List<String> revenueQuarterLabels = new ArrayList<>();
            List<String> ordersQuarterLabels = new ArrayList<>();
            for (int i = 1; i <= currentQuarterValue; i++) {
                revenueQuarterLabels.add(i + "季度");
                ordersQuarterLabels.add(i + "季度");
            }
            context.setVariable("revenueQuarterLabels", revenueQuarterLabels);
            context.setVariable("ordersQuarterLabels", ordersQuarterLabels);
            List<Double> revenueQuarterData = new ArrayList<>();
            List<Integer> ordersQuarterData = new ArrayList<>();
            for (int quarter = 1; quarter <= currentQuarterValue; quarter++) {
                int startMonth = (quarter - 1) * 3 + 1;
                int endMonth = quarter * 3;
                LocalDate startDate = LocalDate.of(year, startMonth, 1);
                LocalDate endDate = LocalDate.of(year, endMonth, 1).withDayOfMonth(
                        LocalDate.of(year, endMonth, 1).lengthOfMonth()
                );
                String fds = startDate.format(formatter);
                String lds = endDate.format(formatter);
                BigDecimal money = service.getTotalMoneyByDate(fds, lds);
                revenueQuarterData.add(money != null ? money.doubleValue() : 0.0);
                int orderNum = service.getOrderCountByLongDate(fds, lds);
                ordersQuarterData.add(orderNum);
            }
            context.setVariable("revenueQuarterData", revenueQuarterData);
            context.setVariable("ordersQuarterData", ordersQuarterData);
            List<String> revenueYearLabels = new ArrayList<>();
            List<Double> revenueYearData = new ArrayList<>();
            List<String> ordersYearLabels = new ArrayList<>();
            List<Integer> ordersYearData = new ArrayList<>();
            for (int i = 3; i >= 0; i--) {
                int year1 = year - i;
                revenueYearLabels.add(String.valueOf(year1));
                ordersYearLabels.add(String.valueOf(year1));
            }
            for (int i = 3; i >= 0; i--) {
                int year1 = year - i;
                String startDate = year1 + "-01-01";  // 构造该年的第一天和最后一天
                String endDate = year1 + "-12-31";
                BigDecimal money = service.getTotalMoneyByDate(startDate, endDate);
                revenueYearData.add(money != null ? money.doubleValue() : 0.0);
                int orderNum = service.getOrderCountByLongDate(startDate, endDate);
                ordersYearData.add(orderNum);
            }
            context.setVariable("revenueYearLabels", revenueYearLabels);
            context.setVariable("revenueYearData", revenueYearData);
            context.setVariable("ordersYearLabels", ordersYearLabels);
            context.setVariable("ordersYearData", ordersYearData);

            LocalDate monday = now.with(java.time.temporal.TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));  // 获取本周的星期一（如果今天是周日，则返回上周一）
            String mondayStr = monday.format(formatter);
            LocalDate sunday = now.with(java.time.temporal.TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));  // 获取本周的星期日
            String sundayStr = sunday.format(formatter);
            context.setVariable("topRoutes",service.getTop5RoutesByDate(mondayStr,sundayStr));

            List<Integer> loadFactorData = new ArrayList<>();
            loadFactorData.add(service.getEconomyOrderCountByLongDate(mondayStr, sundayStr));
            loadFactorData.add(service.getBusinessOrderCountByLongDate(mondayStr, sundayStr));
            loadFactorData.add(service.getFirstOrderCountByLongDate(mondayStr, sundayStr));
            context.setVariable("loadFactorData", loadFactorData);

            int totalFlightNum = service.getTotalFlightNum();
            int totalDelayFlightNum = service.getTotalDelayFlightNum();
            double punctualityRate = (double) (totalFlightNum - totalDelayFlightNum) / totalFlightNum * 100;
            BigDecimal rate = new BigDecimal(punctualityRate).setScale(2, RoundingMode.HALF_UP);
            context.setVariable("punctualityRate", rate.doubleValue());

            List<String> userDistributionLabels = new ArrayList<>();
            List<Integer> userDistributionData = new ArrayList<>();
            List<CityCount> cityCounts = service.getTop6Cities();
            for(CityCount cityCount : cityCounts){
                userDistributionLabels.add(cityCount.getCity());
                userDistributionData.add(cityCount.getCount());
            }
            context.setVariable("userDistributionLabels", userDistributionLabels);
            context.setVariable("userDistributionData", userDistributionData);
            context.setVariable("managername",manager.getM_name());
            ThymeleafUtil.process("manager_report.html", context, resp.getWriter());
        }
    }
}
